{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 填空题"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 介绍：本程序是一个单层神经网络做分类预测的程序。运行的数据集是MNIST数据集，损失函数是交叉熵函数，预测出来的精度在85% 以上，（执行的时候，先位置在前面的程序，然后执行自己补全的程序）（注：机器需要先安装好 numpy 和 tensorflow,装anaconda即可，它包含了numpy库，下载地址  清华映像）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# -*- coding: utf-8 -*-\n",
    "\n",
    "import numpy as np\n",
    "from tensorflow.examples.tutorials.mnist import input_data\n",
    "\n",
    "class Model():\n",
    "    def __init__(self):\n",
    "        mnist = input_data.read_data_sets('MNIST_data', one_hot=True)\n",
    "        self.n_in = 784  # 每张图片是 28 *28 像素\n",
    "        self.n_out = 10  # 总共有 10个类\n",
    "        self.max_epochs = 10000  # 最大训练步数 1000步\n",
    "        self.Weights = np.random.rand(self.n_in,self.n_out) # initialize W 0\n",
    "\n",
    "        self.biases = np.zeros(self.n_out)  # initialize bias 0\n",
    "        for i in range(self.max_epochs):\n",
    "            batch_xs, batch_ys = mnist.train.next_batch(100)\n",
    "            batch_xs = np.array(batch_xs)\n",
    "            batch_ys = np.array(batch_ys)\n",
    "\n",
    "            self.train(batch_xs, batch_ys, 0.0001)\n",
    "            if i % 500 == 0: \n",
    "                accuracy_test = self.compute_accuracy(np.array(mnist.test.images[:500]), np.array(mnist.test.labels[:500]))\n",
    "                print(\"#\"*30)\n",
    "                print(\"compute_accuracy:\",accuracy_test)\n",
    "                print(\"cross_entropy:\",self.cross_entropy(batch_ys,self.output(batch_xs) )) # 输出交叉熵损失函数\n",
    "    def train(self,batch_x,batch_y, learning_rate):# 训练数据 更新权重\n",
    "        #在下面补全（注意对齐空格）\n",
    "        \n",
    "        \n",
    "        \n",
    "        \n",
    "        \n",
    "        \n",
    "        \n",
    "        \n",
    "        \n",
    "        \n",
    "        \n",
    "        \n",
    "        \n",
    "        \n",
    "\n",
    "\n",
    "    def output(self, batch_x):# 输出预测值\n",
    "        # 注意防止 上溢出和下溢出\n",
    "        def softmax(x):\n",
    "            e_x = np.exp(x-np.max(x))\n",
    "            return e_x / (e_x.sum(axis=0)) +1e-30  #\n",
    "        prediction = np.add(np.dot(batch_x, self.Weights),self.biases)\n",
    "        result =[]\n",
    "        for i in range(len(prediction)):\n",
    "            result.append(softmax(prediction[i]))\n",
    "        return np.array(result)\n",
    "        \n",
    "    def cross_entropy(self,batch_y,prediction_y): #交叉熵函数\n",
    "        cross_entropy = - np.mean(\n",
    "            np.sum(batch_y * np.log(prediction_y),axis=1))\n",
    "        return cross_entropy\n",
    "        \n",
    "    def compute_accuracy(self,xs, ys):# 计算预测精度\n",
    "        pre_y = self.output(xs)\n",
    "        pre_y_index = np.argmax(pre_y,axis =1)\n",
    "        y_index = np.argmax(ys,axis =1)\n",
    "        count_equal = np.equal(y_index,pre_y_index)\n",
    "        count = np.sum([1 for e in count_equal if e ])\n",
    "        sum_count =len(xs)\n",
    "        return  count * 1.0 / sum_count\n",
    "Model()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda root]",
   "language": "python",
   "name": "conda-root-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
